#include "stdio.h"
#include "music.h"
#include "string.h"
#include "../fatfs/ff.h"
#include "driver/i2s_std.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "../max9857a/include/max9857a.h"

/*打印WAV文件的信息*/
void Get_WAV_Info(WavHeader * head, char * filename)
{
    FIL fp;
    FRESULT res =  f_open (&fp, filename, FA_READ);
    if(res == FR_OK) 
    {
        printf("打开文件成功\r\n");
        UINT br;
        f_read(&fp, head, sizeof(WavHeader), &br);
        printf("实际读到的 %d 个数据\r\n", (int)br);
        f_close(&fp);
        printf("/*********************************************/\r\n");
        printf("音频编码格式\t %s \t\r\n", (head->fmt.audio_format == 1) ? "PCM/非压缩格式" : "其他");
        printf("声道数      \t %d \t\r\n", (unsigned int)(head->fmt.num_channels));
        printf("采样率      \t %d \t\r\n", (unsigned int)(head->fmt.sample_rate));
        printf("位深        \t %d \t\r\n", head->fmt.bits_per_sample);
        printf("/*********************************************/\r\n");
    }
    else 
    {
        printf("文件名称: %s\r\n", filename);
        printf("打开文件失败,原因 : %d \r\n", (int)res);
        return ;
        
    }
}
/*队列项目数量*/
#define QUEUE_ITEM_NUM 3
/*队列项目长度*/
#define QUEUE_ITEM_SIZE 1024 * 20 
/*队列句柄*/
QueueHandle_t xQueue;
/*队列结构体*/
StaticQueue_t queue_struct;

/*读取任务*/
void read_task(void * arg);
//播放任务
void play_task(void * arg);


/*读取完毕标致*/
int read_end_flag = 0;
/*播放完毕标致*/
int play_end_flag = 0;


/*播放音乐*/
void Play_music(char * filename)
{
    static int I2S_init_flag = 0;
    if(I2S_init_flag == 0)
    {
        I2S_Init();
        I2S_init_flag = 1;
    }
    /*输出wav信息*/
    WavHeader head = {0};
    Get_WAV_Info(&head, filename);

    /*I2S通道配置*/
    i2s_chan_handle_t * I2S_tx_handle = Max9875a_init((unsigned int)(head.fmt.sample_rate), (unsigned int)(head.fmt.num_channels), head.fmt.bits_per_sample);
    printf("I2S_tx_handle = %p\r\n", I2S_tx_handle);
    
    /*队列的缓存位置*/
    uint8_t * queue_buff = malloc(QUEUE_ITEM_NUM * QUEUE_ITEM_SIZE);
    if(queue_buff == NULL)
    {
        printf("队列的缓存申请失败\r\n");
        return;
    }
    else
    {
        printf("队列的缓存申请成功\r\n");
    }
    /*静态创建队列*/
    xQueue = xQueueCreateStatic(
                                QUEUE_ITEM_NUM ,       /*队列的项目数*/
                                QUEUE_ITEM_SIZE,       /*队列项大小*/
                                queue_buff,            /*静态缓冲区*/
                                &queue_struct);        /*队列数据结构体*/
    if(xQueue == NULL)
    {
        printf("队列创建失败\r\n");
        return;
    }
    else
    {
        printf("队列创建成功\r\n");
    }

    /*创建读取数据任务*/
    TaskHandle_t read_task_bandle;
    /*创建播放任务*/
    xTaskCreatePinnedToCore(    read_task, 
                                "read_task", 
                                1024 * 10, 
                                filename, 
                                1, /*与app_main优先级一样*/
                                &read_task_bandle, 
                                0);
    vTaskDelay(500);
    /*创建播放数据任务*/
    TaskHandle_t play_task_bandle;
    /*创建播放任务*/
    xTaskCreatePinnedToCore(    play_task, 
                                "play_task", 
                                1024 * 10, 
                                I2S_tx_handle, 
                                1, /*与app_main优先级一样*/
                                &play_task_bandle, 
                                0);
    
    while(1)
    {
        if(play_end_flag == 1)
        {
            play_end_flag = 0;
            break;
        }
    }
   
        
}


/*读取任务*/
void read_task(void * arg)
{
    read_end_flag = 0;
    while(1)
    {
        FIL fp;
        FRESULT res = f_open (&fp, (char *)arg,FA_READ);
        if(res == FR_OK)
        {
            printf("打开wav文件成功\r\n");
        }
        else 
        {
            printf("打开文件失败,原因 : %d\r\n", (int)res);
            return ;
        }
        char * buf = malloc(QUEUE_ITEM_SIZE);
        if(buf == NULL)
        {
            printf("read临时缓存申请失败\r\n");
            return;
        }
        else
        {
            printf("read临时缓存申请成功\r\n");
        }
        UINT br;
        while(!f_eof(&fp))
        { 
            f_read (&fp, buf, QUEUE_ITEM_SIZE, &br);
            xQueueSend(    xQueue,             /*队列句柄*/
                            buf,               /*要入队的数据*/
                            portMAX_DELAY);     /*死等，直到入队完成*/
        }
        read_end_flag = 1;
        free(buf);
        f_close(&fp);
        vTaskDelete(NULL);   
    }  
}



/*播放任务*/
void play_task(void * arg)
{
    play_end_flag = 0;
    char * play_buf = malloc(QUEUE_ITEM_SIZE);
    if(play_buf == NULL)
    {
        printf("play临时缓存申请失败\r\n");
        return;
    }
    else
    {
        printf("play临时缓存申请成功\r\n");
    }

    while(1)
    {
        if((read_end_flag == 1) && (uxQueueMessagesWaiting(xQueue) == 0))
        {
            break;
        }
        if(uxQueueMessagesWaiting(xQueue) == 0) printf("队列空了\r\n");
        xQueueReceive( xQueue,
                        play_buf,
                        portMAX_DELAY);
        i2s_channel_write(*(i2s_chan_handle_t *)arg, play_buf, QUEUE_ITEM_SIZE, NULL, portMAX_DELAY);
    }
    ESP_ERROR_CHECK(i2s_channel_disable(*(i2s_chan_handle_t *)arg)); 

    free(play_buf);
    read_end_flag = 0;
    play_end_flag = 1;
    vTaskDelete(NULL);
}
